package com.alibaba.citrus.ots.platform.enhance.repository.impl;

import com.alibaba.citrus.ots.common.util.DateUtils;
import com.alibaba.citrus.ots.platform.enhance.repository.InventoryAllotQueryRepository;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByIds2Request;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByIds2Response;
import com.epoch.app.bcots.model.dto.OrganizationSDO;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.otsplatformenhance.enums.InventoryAllotTypeEnum;
import com.epoch.app.otsplatformenhance.inventoryallot.dto.LoadRequest;
import com.epoch.app.otsplatformenhance.inventoryallot.dto.QueryListRequest;
import com.epoch.app.otsplatformenhance.inventoryallot.model.InventoryAllot;
import com.epoch.app.otsplatformenhance.inventoryallot.service.InventoryAllotService;
import com.epoch.app.otsplatformenhance.inventoryallotline.dto.LoadInventoryAllotLineRequest;
import com.epoch.app.otsplatformenhance.inventoryallotline.model.InventoryAllotLine;
import com.epoch.app.otsplatformenhance.inventoryallotline.service.InventoryAllotLineService;
import com.epoch.app.otsplatformenhance.model.dto.*;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
public class InventoryAllotQueryRepositoryImpl implements InventoryAllotQueryRepository {

    @Autowired
    private InventoryAllotService inventoryAllotService;

    @Autowired
    private InventoryAllotLineService inventoryAllotLineService;

    @Autowired
    private BaseDataService baseDataService;

    @Override
    public Result<List<InventoryAllotSDO>> pageQuery(PageQueryInventoryAllotRequest request) {
        InventoryAllotLoadListRequest loadListRequest = pageQueryConvert(request);
        Result<List<InventoryAllot>> listResult = inventoryAllotService.loadList(loadListRequest);
        if (CollectionUtils.isNotEmpty(listResult.getResult())) {
            List<InventoryAllotSDO> inventoryAllotSDOS = listResult.getResult().stream().map(result -> {
                InventoryAllotSDO inventoryAllotSDO = getInventoryAllotSDO(result);
                return inventoryAllotSDO;
            }).collect(Collectors.toList());
            return Result.listSuccess(inventoryAllotSDOS, listResult.getTotal());
        }
        return Result.success(null);
    }

    @Override
    public Result<InventoryAllotSDO> queryById(InventoryAllotQueryByIdRequest inventoryAllotQueryByIdRequest) {
        LoadRequest loadRequest = new LoadRequest();
        loadRequest.setId(Long.parseLong(inventoryAllotQueryByIdRequest.getId()));
        InventoryAllot load = inventoryAllotService.load(loadRequest);
        if (load == null || load.getId() == null) {
            return Result.success(null);
        }
        InventoryAllotSDO inventoryAllotSDO = getInventoryAllotSDO(load);
        InventoryAllotLineLoadListRequest request = new InventoryAllotLineLoadListRequest();
        request.setInventoryAllotId(inventoryAllotQueryByIdRequest.getId());
        request.setScItemIdList(inventoryAllotQueryByIdRequest.getScItemId() == null ? null : Collections.singletonList(inventoryAllotQueryByIdRequest.getScItemId()));
        request.setStart(0);
        request.setLimit(1000);
        Result<List<InventoryAllotLine>> firstListResult = inventoryAllotLineService.loadInventoryAllotLineList(request);
        if (Objects.isNull(firstListResult) || CollectionUtils.isEmpty(firstListResult.getResult())) {
            return Result.success(null);
        }
        List<InventoryAllotLine> totalResult = new ArrayList<>();
        int total = firstListResult.getTotal();
        if (total > 1000) {
            int page = total / 1000;
            for (int i = 0; i <= page; i++) {

                request.setStart(i * 1000);
                request.setLimit(1000);
                Result<List<InventoryAllotLine>> listResult = inventoryAllotLineService.loadInventoryAllotLineList(request);
                if (Objects.nonNull(listResult) && CollectionUtils.isNotEmpty(listResult.getResult())) {
                    totalResult.addAll(listResult.getResult());
                }
            }

        } else {
            totalResult.addAll(firstListResult.getResult());
        }
        if (CollectionUtils.isNotEmpty(totalResult)) {
            List<InventoryAllotLineSDO> collect = totalResult.stream().map(result -> {
                InventoryAllotLineSDO inventoryAllotLineSDO = new InventoryAllotLineSDO();
                inventoryAllotLineSDO.setId(result.getId().toString());
                inventoryAllotLineSDO.setInventoryAllotId(result.getInventoryAllotId());
                inventoryAllotLineSDO.setScItemId(result.getScItemId());
                inventoryAllotLineSDO.setScItemName(result.getScItemName());
                inventoryAllotLineSDO.setAvailableInventory(result.getAvailableInventory());
                inventoryAllotLineSDO.setAdjustInventory(result.getAdjustInventory());
                inventoryAllotLineSDO.setImportInventory(result.getImportInventory());
                inventoryAllotLineSDO.setDimensionName(result.getDimensionName());
                inventoryAllotLineSDO.setDimensionId(result.getDimensionId());
                inventoryAllotLineSDO.setCalculationScale(result.getCalculationScale());
                inventoryAllotLineSDO.setDistributionQuantity(result.getDistributionQuantity());
                inventoryAllotLineSDO.setInventoryUnit(result.getInventoryUnit());
                inventoryAllotLineSDO.setCreator(result.getCreator());
                inventoryAllotLineSDO.setGmtCreate(result.getGmt_create());
                inventoryAllotLineSDO.setModifier(result.getUpdater());
                inventoryAllotLineSDO.setGmtModified(result.getGmt_modified());
                if (StringUtils.isNotEmpty(result.getFeature())) {
                    Map<String, String> map = JSONObject.parseObject(result.getFeature(), new TypeReference<Map<String, String>>() {
                    });
                    inventoryAllotLineSDO.setFeatures(result.getFeature());
                    inventoryAllotLineSDO.setScItemOuterId(map.get("sc_item_outer_id"));
                    inventoryAllotLineSDO.setDimensionOutId(map.get("dimension_out_id"));
                }
                return inventoryAllotLineSDO;
            }).collect(Collectors.toList());
            inventoryAllotSDO.setInventoryAllotLineSDOS(collect);
        }
        return Result.success(inventoryAllotSDO);
    }

    @Override
    public Result<List<InventoryAllotExcelExportResponse>> excelExPort(PageQueryInventoryAllotRequest inventoryAllotExcelExportRequest) {
        LoadRequest loadRequest = new LoadRequest();
        loadRequest.setId(inventoryAllotExcelExportRequest.getId());
        InventoryAllot inventoryAllot = inventoryAllotService.load(loadRequest);
        if (inventoryAllot == null) {
            return Result.success(null);
        }
        List<String> orgList = new ArrayList<>();
        orgList.add(inventoryAllot.getOrganizationCode());
        Map<String, OrganizationSDO> organizationSDOMap = getOrganizationMap(orgList);
        List<InventoryAllotExcelExportResponse> listResponse = new ArrayList<>();
        InventoryAllotExcelExportResponse response = new InventoryAllotExcelExportResponse();
        response.setId(inventoryAllot.getId().toString());
        if (InventoryAllotTypeEnum.CHANNEL.getCode().equals(inventoryAllot.getDistributionType())) {
            response.setDistributionTypeDesc(InventoryAllotTypeEnum.CHANNEL.getDesc());
        }
        if (InventoryAllotTypeEnum.DEPARTMENT.getCode().equals(inventoryAllot.getDistributionType())) {
            response.setDistributionTypeDesc(InventoryAllotTypeEnum.DEPARTMENT.getDesc());
        }
        if (InventoryAllotTypeEnum.SALESMAN.getCode().equals(inventoryAllot.getDistributionType())) {
            response.setDistributionTypeDesc(InventoryAllotTypeEnum.SALESMAN.getDesc());
        }
        response.setDistributionId(inventoryAllot.getDistributionId());
        response.setInventoryAllotTime(inventoryAllot.getInventoryAllotTime());
        if (inventoryAllot.getInventoryAllotTime() != null) {
            String dateStr = DateUtils.formatDate(inventoryAllot.getInventoryAllotTime(), DateUtils.DATE_FORMAT);
            response.setInventoryAllotDate(dateStr);
        }
        //response.setValidBeginTime(inventoryAllot.getValidBeginTime());
        //response.setValidEndTime(inventoryAllot.getValidEndTime());
        response.setOrganizationCode(inventoryAllot.getOrganizationCode());
        response.setOrganizationName(inventoryAllot.getOrganizationName());
        response.setDailyBeginTime(inventoryAllot.getDailyBeginTime());
        response.setDailyEndTime(inventoryAllot.getDailyEndTime());

        InventoryAllotLineLoadListRequest lineRequest = new InventoryAllotLineLoadListRequest();
        lineRequest.setStart(inventoryAllotExcelExportRequest.getStart());
        lineRequest.setLimit(inventoryAllotExcelExportRequest.getLimit());
        lineRequest.setInventoryAllotId(inventoryAllot.getId().toString());
        Result<List<InventoryAllotLine>> lineResult = inventoryAllotLineService.loadInventoryAllotLineList(lineRequest);
        for (InventoryAllotLine inventoryAllotLine : lineResult.getResult()) {
            InventoryAllotExcelExportResponse responseReal = new InventoryAllotExcelExportResponse();
            BeanUtils.copyProperties(response, responseReal);
            //报表导出商品id和维度id均为外部id modify by wangzq
            if (org.apache.commons.lang.StringUtils.isNotEmpty(inventoryAllotLine.getFeature())) {
                Map<String, String> map = JSONObject.parseObject(inventoryAllotLine.getFeature(), new TypeReference<Map<String, String>>() {
                });
                responseReal.setScItemId(map.get("sc_item_outer_id"));
                responseReal.setDimensionId(map.get("dimension_out_id"));
            }
            //组织编码转换为外部编码
            OrganizationSDO sdo = organizationSDOMap.get(responseReal.getOrganizationCode());
            responseReal.setOrganizationCode(sdo.getOutCode());
            responseReal.setScItemName(inventoryAllotLine.getScItemName());
            responseReal.setAvailableInventory(inventoryAllotLine.getAvailableInventory());
            responseReal.setAdjustInventory(inventoryAllotLine.getAdjustInventory());
            responseReal.setImportInventory(inventoryAllotLine.getImportInventory());
            responseReal.setDimensionName(inventoryAllotLine.getDimensionName());
            responseReal.setCalculationScale(inventoryAllotLine.getCalculationScale());
            responseReal.setDistributionQuantity(inventoryAllotLine.getDistributionQuantity());
            responseReal.setInventoryUnit(inventoryAllotLine.getInventoryUnit());
            listResponse.add(responseReal);
        }
        return Result.listSuccess(listResponse, listResponse.size());
    }

    private Map<String, OrganizationSDO> getOrganizationMap(List<String> orgIds) {
        BaselineGetOrganizationByIds2Request orgQueryReqById = new BaselineGetOrganizationByIds2Request();
        orgQueryReqById.setIds(orgIds);
        BaselineGetOrganizationByIds2Response getOrgsResponse = baseDataService.baselineGetOrganizationByIds2(orgQueryReqById);
        Map<String, OrganizationSDO> orgsMap = Nullable.stream(getOrgsResponse.getResult()).collect(Collectors.toMap(OrganizationSDO::getId, Function.identity(), (v1, v2) -> v1));
        return orgsMap;
    }

    @Override
    public Result<InventoryAllot> queryList(QueryListRequest queryAllotRequest) {
        InventoryAllot inventoryAllot = new InventoryAllot();
//        QueryListRequest queryListRequest = new QueryListRequest();
//        queryListRequest.setOrganizationCode(queryAllotRequest.getOrganizationCode());
//        queryListRequest.setDistributionType(queryAllotRequest.getDistributionType());
        InventoryAllotLoadListRequest request = new InventoryAllotLoadListRequest();
        request.setOrganizationCode(queryAllotRequest.getOrganizationCode());
        request.setDistributionType(queryAllotRequest.getDistributionType());
        Result<List<InventoryAllot>> inventoryAllotResult = inventoryAllotService.loadList(request);
        if (inventoryAllotResult != null && CollectionUtils.isNotEmpty(inventoryAllotResult.getResult())) {
            inventoryAllot = inventoryAllotResult.getResult().get(0);
            return Result.success(inventoryAllot);
        }
        return Result.success(null);
    }

    @Override
    public InventoryAllotLineSDO queryLineById(String id) {
        LoadInventoryAllotLineRequest request = new LoadInventoryAllotLineRequest(Long.parseLong(id));
        InventoryAllotLine inventoryAllotLine = inventoryAllotLineService.loadInventoryAllotLine(request);
        InventoryAllotLineSDO inventoryAllotLineSDO = new InventoryAllotLineSDO();
        BeanUtils.copyProperties(inventoryAllotLine, inventoryAllotLineSDO);
        return inventoryAllotLineSDO;
    }

    @Override
    public Result<List<InventoryAllot>> queryAllotListByCondition(QueryAllotListRequest queryAllotListRequest) {
        return inventoryAllotService.queryAllotListByCondition(queryAllotListRequest);
//        return null;
    }

    @NotNull
    private InventoryAllotSDO getInventoryAllotSDO(InventoryAllot result) {
        InventoryAllotSDO inventoryAllotSDO = new InventoryAllotSDO();
        if (result.getId() != null) {
            inventoryAllotSDO.setId(result.getId().toString());
        }
        String distributionType = result.getDistributionType();
        inventoryAllotSDO.setDistributionType(distributionType);
        if (InventoryAllotTypeEnum.CHANNEL.getCode().equals(distributionType)) {
            inventoryAllotSDO.setDistributionTypeDesc(InventoryAllotTypeEnum.CHANNEL.getDesc());
        }
        if (InventoryAllotTypeEnum.DEPARTMENT.getCode().equals(distributionType)) {
            inventoryAllotSDO.setDistributionTypeDesc(InventoryAllotTypeEnum.DEPARTMENT.getDesc());
        }
        if (InventoryAllotTypeEnum.SALESMAN.getCode().equals(distributionType)) {
            inventoryAllotSDO.setDistributionTypeDesc(InventoryAllotTypeEnum.SALESMAN.getDesc());
        }
        inventoryAllotSDO.setDistributionId(result.getDistributionId());
        inventoryAllotSDO.setOrganizationCode(result.getOrganizationCode());
        inventoryAllotSDO.setOrganizationName(result.getOrganizationName());
        //inventoryAllotSDO.setValidBeginTime(result.getValidBeginTime());
        //inventoryAllotSDO.setValidEndTime(result.getValidEndTime());
        inventoryAllotSDO.setInventoryAllotTime(result.getInventoryAllotTime());
        if (result.getInventoryAllotTime() != null) {
            String dateStr = DateUtils.formatDate(result.getInventoryAllotTime(), DateUtils.DATE_FORMAT);
            inventoryAllotSDO.setInventoryAllotDate(dateStr);
        }
        inventoryAllotSDO.setCreatorId(result.getCreatorId());
        inventoryAllotSDO.setCreator(result.getCreator());
        inventoryAllotSDO.setDailyBeginTime(result.getDailyBeginTime());
        inventoryAllotSDO.setDailyEndTime(result.getDailyEndTime());
        inventoryAllotSDO.setLimitSwitch(result.getLimitSwitch());
        HashMap<String, String> limitSwitchObj = new HashMap<>();
        if (result.getLimitSwitch()){
            limitSwitchObj.put("text","是");
            limitSwitchObj.put("value","true");

        }else {
            limitSwitchObj.put("text","否");
            limitSwitchObj.put("value","false");
        }
        inventoryAllotSDO.setLimitSwitchObj(limitSwitchObj);

        if (result.getGmt_create().before(DateUtils.getNowWithoutHours())) {
            Map<String, String> statusLabel = new HashMap<>();
            inventoryAllotSDO.setStatus("已失效");
            statusLabel.put("text", "已失效");
            statusLabel.put("type", "cancel");
            inventoryAllotSDO.setStatusLabel(statusLabel);
        } else {
            if (result.getValidBeginTime() != null && result.getValidEndTime() != null) {
                Map<String, String> statusLabel = new HashMap<>();
                if (result.getValidBeginTime().after(new Date())) {
                    inventoryAllotSDO.setStatus("未生效");
                    statusLabel.put("text", "未生效");
                    statusLabel.put("type", "warning");
                }
                if (result.getValidBeginTime().before(new Date()) && result.getValidEndTime().after(new Date())) {
                    inventoryAllotSDO.setStatus("生效中");
                    statusLabel.put("text", "生效中");
                    statusLabel.put("type", "success");
                }
                if (result.getValidEndTime().before(new Date())) {
                    inventoryAllotSDO.setStatus("已失效");
                    statusLabel.put("text", "已失效");
                    statusLabel.put("type", "cancel");
                }
                inventoryAllotSDO.setStatusLabel(statusLabel);
            }
        }

        return inventoryAllotSDO;
    }


    @NotNull
    private InventoryAllotLoadListRequest pageQueryConvert(PageQueryInventoryAllotRequest request) {
        InventoryAllotLoadListRequest loadListRequest = new InventoryAllotLoadListRequest();
        loadListRequest.setOrganizationCode(request.getOrgId());
        loadListRequest.setOrganizationCodes(request.getOrgIds());
        loadListRequest.setId(request.getId());
        if (CollectionUtils.isNotEmpty(request.getDateList())) {
            SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.DATETIME_FORMAT);
            try {
                loadListRequest.setInventoryAllotBeginTime(sdf.parse(request.getDateList().get(0)));
                loadListRequest.setInventoryAllotEndTime(sdf.parse(request.getDateList().get(1).substring(0, 10) + " 23:59:59"));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        loadListRequest.setAsc(false);
        loadListRequest.setStart(request.getStart());
        loadListRequest.setLimit(request.getLimit());
        loadListRequest.setDir("gmt_create");
        return loadListRequest;
    }
}
